Consider the following operation on an arbitrary positive integer:

  • If the number is even, divide it by two.
  • If the number is odd, triple it and add one.

We will stop at 1.

Hailstone Number

The 3n + 1 problem

Collatz conjecture

Stanislaw Ulam


In [1]:
def f(i):
    yield i
    while i > 1:
        if i % 2 == 0:
            i //= 2
        else:
            i = 3 * i + 1
        yield i

In [2]:
list(f(22))


Out[2]:
[22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

In [3]:
def get_stopping_time(i):
    return len(list(f(i)))

In [4]:
assert get_stopping_time(22) == 16

In [5]:
def get_stopping_time(i):
    '''Directly calculates "stopping time",
    without saving the hailstone numbers.'''
    n = 1
    while i > 1:
        if i % 2 == 0:
            i //= 2
        else:
            i = 3 * i + 1
        n += 1
    return n

In [6]:
assert get_stopping_time(22) == 16

In [7]:
def foo(i, j):
    return max(get_stopping_time(k) for k in range(i, j+1))

In [8]:
# From bottom of https://uva.onlinejudge.org/external/1/100.html

sample_input_output = '''1 10 20
100 200 125
201 210 89
900 1000 174'''

In [9]:
for line in sample_input_output.split('\n'):
    i, j, expected_output = [int(s) for s in line.split()]
    actual_output = foo(i, j)
    assert actual_output == expected_output
    print(i, j, actual_output)


1 10 20
100 200 125
201 210 89
900 1000 174